/*
 * Project: BooEditor
 * Author:  Johannes Kuhaupt
 * Copyright (c): Johannes Kuhaupt
 * Licence: MIT
 */
package control.boo;

import control.GuiManager;
import control.SettingsManager;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Johannes Kuhaupt
 */
public class BooCompiler extends AbstractBooTask{
    
    private boolean compileToDll;
    
    
    /**
     *
     * @param pFile
     */
    public BooCompiler(String pFile, boolean pCompileToDll) {
        this.taskFile = new File(pFile);
        this.compileToDll = pCompileToDll;
    }

    /**
     *
     */
    @Override
    public void run() {
        this.guiMan.setBooReady(false);
        this.startBooTask();
    }

    
    
    private void startBooTask() {
        compilerResult = "";
        currentProcess = null;
        processStarted = false;
        
        if(SettingsManager.getBooleanSettingValue("MONO")){
            this.startBooTaskWithMono();
        }
        else{
            this.startBooTaskWithNet();
        }
        
        if(processStarted){
                this.readOutputStream();
                this.guiMan.setBooReady(true);
                
                if(this.compilerResult.startsWith("Boo Compiler version")&&lineCount==1){
                    this.guiMan.setOutputInFrame(GuiManager.getLangBundle().getString("MsgSuccessCompiling"));                    
                    this.guiMan.setStatusInfo(GuiManager.getLangBundle().getString("StatusMsgCompileSuccess"));
                }
                else{
                    this.guiMan.setOutputInFrame(this.compilerResult);
                    this.guiMan.setStatusInfo(GuiManager.getLangBundle().getString("StatusMsgCompileError"));
                    this.guiMan.showOutputTab();
                }
            
                
            }
        
    }
    
    
    private void startBooTaskWithMono() {
        
        path = new File(taskFile.getParent());
        
        

        File booExe = new File(pathToBoo);
        File monoExe = new File(pathToMono);
        if(booExe.getName().equals("booi.exe")){
            booExe = new File(booExe.getParent());
            booExe=new File(booExe.getAbsolutePath()+File.separator+"booc.exe");
            this.startBooTaskWithLinxAndMonoAndBooExe(booExe,monoExe );
        }
        else if(booExe.getName().equals("booi")){
            booExe = new File(booExe.getParent());
            booExe=new File(booExe.getAbsolutePath()+File.separator+"booc");
            this.startBooTaskWithMonoAndLinuxShellScript(booExe,monoExe );
        }
        else{
            this.guiMan.showErrorMessage(GuiManager.getLangBundle().getString("MsgErrorBooc"));
            this.guiMan.setBooReady(true);  
        }
        
        
        
        
        
        
        
    }

    private void startBooTaskWithNet() {

        File path = new File(taskFile.getParent());
        String pathToBoo = SettingsManager.getStringSettingValue("PATH_TO_BOO");

        File booExe = new File(pathToBoo);
        booExe = new File(booExe.getParent());
        booExe=new File(booExe.getAbsolutePath()+File.separator+"booc.exe");
        if(booExe.exists() && booExe.canExecute() && (booExe.getName().equals("booc.exe")||booExe.getName().equals("booc"))){
            if(this.compileToDll){
                pb = new ProcessBuilder(booExe.getAbsolutePath(),"-t:library","-out:"+this.getFileWithoutEnding(taskFile)+".dll" ,taskFile.getName());
            }
            else{
                pb = new ProcessBuilder(booExe.getAbsolutePath(), taskFile.getName());
                
            }
            pb = new ProcessBuilder(booExe.getAbsolutePath(), taskFile.getName());
            pb.redirectErrorStream(true);
            pb.directory(path);

            try {
                currentProcess = pb.start();
                processStarted = true;
            } catch (IOException ex) {
                this.guiMan.setOutputInFrame(this.compilerResult);
                this.guiMan.setBooReady(true);
                this.guiMan.showErrorMessage(GuiManager.getLangBundle().getString("MsgErrorCompiling"));
                Logger.getLogger(BooCompiler.class.getName()).log(Level.SEVERE, null, ex);
                System.err.println("Error, startBooTask failed (Compiling): " + ex.toString());
            }
            
        }
        else{
            this.guiMan.showErrorMessage(GuiManager.getLangBundle().getString("MsgErrorBooc"));
            this.guiMan.setBooReady(true);  
    }

}

    private void startBooTaskWithLinxAndMonoAndBooExe(File booExe, File monoExe) {
        if(booExe.exists() && booExe.canExecute() && booExe.getName().equals("booc.exe") && monoExe.exists() && monoExe.canExecute() && (monoExe.getName().equals("mono.exe")||monoExe.getName().equals("mono"))){
            if(this.compileToDll){
                pb = new ProcessBuilder(pathToMono, booExe.getAbsolutePath(),"-t:library","-out:"+this.getFileWithoutEnding(taskFile)+".dll" ,taskFile.getName());
            }
            else{
                pb = new ProcessBuilder(pathToMono, booExe.getAbsolutePath(), taskFile.getName());
            }

            pb.redirectErrorStream(true);
            pb.directory(path);

            try {
                currentProcess = pb.start();
                processStarted = true;
            } catch (IOException ex) {
                this.guiMan.setOutputInFrame(this.compilerResult);
                this.guiMan.setBooReady(true);
                this.guiMan.showErrorMessage(GuiManager.getLangBundle().getString("MsgErrorCompiling"));
                Logger.getLogger(BooCompiler.class.getName()).log(Level.SEVERE, null, ex);
                System.err.println("Error, startBooTask failed (Compiler): " + ex.toString());
            }
            
        }
        else{
            this.guiMan.showErrorMessage(GuiManager.getLangBundle().getString("MsgErrorBooc"));
            this.guiMan.setBooReady(true);            
        }
    }

    private void startBooTaskWithMonoAndLinuxShellScript(File booExe, File monoExe) {
        if(booExe.exists() && booExe.canExecute() && booExe.getName().equals("booc") && monoExe.exists() && monoExe.canExecute() && (monoExe.getName().equals("mono.exe")||monoExe.getName().equals("mono"))){
            if(this.compileToDll){
                pb = new ProcessBuilder(booExe.getAbsolutePath(),"-t:library","-out:"+this.getFileWithoutEnding(taskFile)+".dll" ,taskFile.getName());
            }
            else{
                pb = new ProcessBuilder(booExe.getAbsolutePath(), taskFile.getName());
            }

            pb.redirectErrorStream(true);
            pb.directory(path);

            try {
                currentProcess = pb.start();
                processStarted = true;
            } catch (IOException ex) {
                this.guiMan.setOutputInFrame(this.compilerResult);
                this.guiMan.setBooReady(true);
                this.guiMan.showErrorMessage(GuiManager.getLangBundle().getString("MsgErrorCompiling"));
                Logger.getLogger(BooCompiler.class.getName()).log(Level.SEVERE, null, ex);
                System.err.println("Error, startBooTask failed (Compiler): " + ex.toString());
            }
            
        }
        else{
            this.guiMan.showErrorMessage(GuiManager.getLangBundle().getString("MsgErrorBooc"));
            this.guiMan.setBooReady(true);            
        }
    }

    
}
